from app.utils.time import get_now_date
from app.utils.uuid import generate_unique_id
from app.utils.password import get_password_hash
from app.database.models import Account, App
from app.database.postgre import SessionDep, col, or_
from app.models import responses
from app.models.common import AccountIdJSON
from app.models.super import (AccountsListParams, CreateAccountJSON, DisableAccountJSON, UpdateAccountJSON,
                              ModifyPasswordJSON, AccountAppListParams, UpdateAccountAppJSON, BatchDeleteAccountsJSON)


async def get_accounts_list(query_params: AccountsListParams, session: SessionDep):
    """获取账号列表"""
    # 构建查询参数
    page = query_params.page
    page_size = query_params.page_size
    username = query_params.username
    identity = query_params.identity

    # 构建查询语句
    query = session.query(Account).order_by(col(Account.id).asc())

    # 动态添加查询条件
    if username:
        query = query.filter(col(Account.username).like(f"%{username}%"))
    if identity is not None:
        query = query.filter(Account.identity == identity)

    # 获取总数
    total_count = query.count()
    total_pages = (total_count + page_size - 1) // page_size

    # 获取分页数据
    offset = (page - 1) * page_size
    paginated_query = query.offset(offset).limit(page_size)
    paginated_accounts = paginated_query.all()

    return responses.SuccessResponse(
        data={
            'total': total_count,
            'total_pages': total_pages,
            'page': page,
            'page_size': len(paginated_accounts),
            'list': [account.model_dump(exclude={'password'}) for account in paginated_accounts]
        }
    )


async def create_new_account(super_account: Account, json_data: CreateAccountJSON, session: SessionDep):
    """创建新的账号"""
    # 构建创建账号的参数
    username = json_data.username
    email = json_data.email
    phone = json_data.phone
    password = json_data.password
    identity = json_data.identity
    max_apps = json_data.max_apps

    existing_account = session.query(Account).filter(
        or_(
            Account.username == username,
            Account.email == email,
            Account.phone == phone
        )
    ).first()

    if existing_account:
        if existing_account.username == username:
            return responses.Response206(msg='用户名已存在')
        if existing_account.email == email:
            return responses.Response206(msg='邮箱已被绑定')
        if existing_account.phone == phone:
            return responses.Response206(msg='手机号已被绑定')

    # 创建新的账号
    account_id = generate_unique_id(optional_params={
        username: username,
        email: email
    })
    hash_password = get_password_hash(password)
    new_account = Account(
        aid=account_id,
        username=username,
        email=email,
        password=hash_password,
        identity=identity,
        max_apps=max_apps,
        avatar="",
        phone=phone,
        remark=f"由 {super_account.username} 添加"
    )
    try:
        session.add(new_account)
        session.commit()
    except Exception as e:
        session.rollback()
        raise e

    session.refresh(new_account)

    return responses.SuccessResponse(msg='账号创建成功', data=new_account.model_dump(exclude={'password'}))


async def disable_account(super_account: Account, json_data: DisableAccountJSON, session: SessionDep):
    """禁用账号"""
    # 构建禁用账号的参数
    account_id = json_data.account_id
    is_banned = json_data.is_banned

    # 获取被修改的账号
    operate_account = Account.get_by_aid(session, account_id)
    if not operate_account:
        return responses.Response209()

    # 不能封禁自己
    if operate_account.aid == super_account.aid and is_banned:
        return responses.Response211()

    # 修改禁用标识，修改登录时间（踢出登录）
    operate_account.is_banned = is_banned
    operate_account.login_time = get_now_date()
    session.commit()
    session.refresh(operate_account)
    return responses.SuccessResponse(
        msg='账号已成功封禁' if is_banned else '账号已成功解封',
        data=operate_account.model_dump(include={'aid', 'is_banned', 'login_time'})
    )


async def update_account(super_account: Account, json_data: UpdateAccountJSON, session: SessionDep):
    """更新账号"""
    # 构建更新账号的参数
    account_id = json_data.account_id
    update_data = json_data.model_dump(exclude={'account_id'}, exclude_none=True)

    # 获取被修改的账号
    operate_account = Account.get_by_aid(session, account_id)
    if not operate_account:
        return responses.Response209()

    # 检查超管自己是否改变自己的权限
    if super_account.aid == json_data.account_id and super_account.identity != json_data.identity:
        return responses.Response213()

    # 检查超管是否将别人提为超管身份
    if super_account.aid != json_data.account_id and super_account.identity == json_data.identity:
        return responses.Response214()

    # 更新账号信息
    Account.sqlmodel_update(operate_account, update_data)
    session.commit()
    session.refresh(operate_account)
    return responses.SuccessResponse(
        msg='账号更新成功',
        data=operate_account.model_dump(exclude={'password'})
    )


async def modify_password_by_super(json_data: ModifyPasswordJSON, session: SessionDep):
    """超管修改密码"""
    # 构建修改密码的参数
    account_id = json_data.account_id
    new_password = json_data.new_password

    # 获取被修改的账号
    operate_account = Account.get_by_aid(session, account_id)
    if not operate_account:
        return responses.Response209()

    # 修改密码，修改登录时间（踢出登录）
    operate_account.password = get_password_hash(new_password)
    operate_account.login_time = get_now_date()
    session.commit()
    session.refresh(operate_account)
    return responses.SuccessResponse(
        msg='密码修改成功，该账号需要重新登录',
        data=operate_account.model_dump(include={'aid', 'login_time'})
    )


async def delete_account_by_id(super_account, json_data: AccountIdJSON, session: SessionDep):
    """删除账号"""
    # 获取被删除的账号
    account_id = json_data.account_id
    operate_account = Account.get_by_aid(session, account_id)
    if not operate_account:
        return responses.Response209()

    # 不能删除自己
    if operate_account.aid == super_account.aid:
        return responses.Response212()

    session.delete(operate_account)
    session.commit()
    return responses.SuccessResponse(msg='账号已删除', data={
        'id': account_id
    })


async def get_account_apps(query_params: AccountAppListParams, session: SessionDep):
    """获取某个账号的应用"""
    # 构建查询参数
    account_id = query_params.account_id
    page = query_params.page
    page_size = query_params.page_size
    name = query_params.name

    # 获取被查询的账号
    operate_account = Account.get_by_aid(session, account_id)
    if not operate_account:
        return responses.Response209()

    # 构建查询语句
    query = session.query(App).filter(App.account_id == operate_account.aid)

    # 动态添加查询条件
    if name:
        query = query.filter(col(App.name).like(f"%{name}%"))

    # 获取总数
    total_count = query.count()
    total_pages = (total_count + page_size - 1) // page_size

    # 获取分页数据
    offset = (page - 1) * page_size
    paginated_query = query.offset(offset).limit(page_size)
    paginated_apps = paginated_query.all()

    return responses.SuccessResponse(
        data={
            'total': total_count,
            'total_pages': total_pages,
            'page': page,
            'page_size': len(paginated_apps),
            'list': [app.model_dump() for app in paginated_apps]
        }
    )


async def update_app(json_data: UpdateAccountAppJSON, session: SessionDep):
    """超管更新应用"""
    other_data = json_data.model_dump(exclude={'app_id'}, exclude_none=True)

    app = session.get(App, json_data.app_id)
    if not app:
        return responses.Response303()

    App.sqlmodel_update(app, other_data)
    session.commit()
    session.refresh(app)

    return responses.SuccessResponse(msg='应用更新成功', data=app.model_dump())


async def delete_account_by_ids(super_account: Account, json_data: BatchDeleteAccountsJSON, session: SessionDep):
    """批量删除账号"""
    accounts = session.query(Account).filter(
        Account.aid != super_account.aid,  # 非自己
        col(Account.aid).in_(json_data.account_ids)  # 满足范围
    ).all()
    if not accounts:
        return responses.SuccessResponse(msg='没有找到指定的账号', data={'count': 0, 'ids': []})

    deleted_ids = [account.id for account in accounts]

    session.query(Account).filter(col(Account.aid).in_(deleted_ids)).delete(synchronize_session=False)
    session.commit()

    return responses.SuccessResponse(msg='选中的账号已删除', data={
        'ids': deleted_ids
    })


async def clear_all_account(super_account: Account, session: SessionDep):
    """清空所有的账号"""
    accounts = session.query(Account).filter(
        Account.aid != super_account.aid,  # 非自己
    ).all()
    if not accounts:
        return responses.SuccessResponse(msg='没有账号可清空', data={'ids': []})

    deleted_ids = [account.aid for account in accounts]

    session.query(Account).filter(col(Account.aid).in_(deleted_ids)).delete(synchronize_session=False)
    session.commit()

    return responses.SuccessResponse(msg='账号已清空', data={
        'ids': deleted_ids
    })
